package edu.dev.tfile;

import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.ssl.SslContextFactory;

import edu.dev.tfile.common.Utils;
import edu.dev.tfile.service.DownloadService;
import edu.dev.tfile.service.OnlineService;
import edu.dev.tfile.service.UploadConfirmService;
import edu.dev.tfile.service.UploadPathService;
import edu.dev.tfile.service.UploadService;
import edu.dev.tfile.service.UserListService;

public class WebServer implements Runnable, TFileListener {

	private Server server = null;

	public WebServer() {
		TFileEventManagement.getManagement().registerListener("webserver", this);
	}

	public void startServer() throws Exception {
		server = new Server();
		HttpConfiguration httpsConf = new HttpConfiguration();
		httpsConf.setSecureScheme("https");
		httpsConf.setSecurePort(Integer.parseInt(Utils.getConfig("server_port")));
		httpsConf.setOutputBufferSize(10240);
		httpsConf.addCustomizer(new SecureRequestCustomizer());

		SslContextFactory sslContextFactory = new SslContextFactory();
		sslContextFactory.setKeyStorePath(Utils.BASE_PATH + "/conf/" + Utils.getConfig("keystore_name"));
		sslContextFactory.setKeyStorePassword(Utils.getConfig("keystore_password"));
		sslContextFactory.setKeyManagerPassword(Utils.getConfig("keymanager_password"));

		ServerConnector httpsConnector = new ServerConnector(server,
				new SslConnectionFactory(sslContextFactory, "http/1.1"), new HttpConnectionFactory(httpsConf));
		httpsConnector.setPort(Integer.parseInt(Utils.getConfig("server_port")));
		httpsConnector.setIdleTimeout(Integer.parseInt(Utils.getConfig("http_connection_timeout")));
		server.addConnector(httpsConnector);

		ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
		context.setContextPath("/");

		context.addServlet(new ServletHolder(new UploadConfirmService()), "/ucs/*");
		context.addServlet(new ServletHolder(new UploadPathService()), "/upath/*");
		context.addServlet(new ServletHolder(new DownloadService()), "/browse/*");
		context.addServlet(new ServletHolder(new OnlineService()), "/online/*");
		context.addServlet(new ServletHolder(new UploadService()), "/upload/*");
		context.addServlet(new ServletHolder(new UserListService()), "/userlist/*");

		ResourceHandler rh = new ResourceHandler();
		rh.setWelcomeFiles(new String[]{"index.html"});
		rh.setResourceBase(Utils.BASE_PATH + "/resources");

		HandlerCollection hc = new HandlerCollection();
		hc.setHandlers(new Handler[] { rh, context });

		server.setHandler(hc);
		server.start();
	}

	@Override
	public void run() {
		try {
			startServer();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void fire(String command) {
		try {
			if ("load".equals(command)) {
				startServer();
			} else if ("start".equals(command)) {
				server.start();
			} else if ("stop".equals(command)) {
				server.stop();
			} else if ("destroy".equals(command)) {
				server.destroy();
				Thread.currentThread().interrupt();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
